readerwriterlock允许在获取写锁定时读取?

我有一个静态类,可以通过多个远程处理和其他内部应用程序线程访问。 该类的部分function是控制对各种文件的读/写访问,因此我在文件列表中实现了静态ReaderWriterLock。 该项目使用.net framework 2.0作为客户需求的一部分。

然而,当我使用许多不同的客户端(通常我使用16个)对系统进行压力测试时,每个客户端执行大量的读写操作,然后非常间歇性地进行,并且仅在经过几个小时甚至几天后,至少完成了500k +次交易。系统崩溃。 好的,我们有一个bug ..

但是当我检查所有锁定事件的日志时,我可以看到发生了以下情况:

1:线程A直接获取写锁定,检查IsWriterLock是否为真。

2:即使线程A仍然具有写锁定,线程B也会尝试获取读取器锁定并成功

3:系统现在崩溃,堆栈跟踪现在显示readerwriterlock的空引用exception

此过程之前已经运行了数十万次而没有错误,我可以检查日志,看到读取锁在之前的所有情况下都被阻止,直到写入退出。 我也尝试将readerwriterlock实现为单例,但问题仍然存在

有没有人见过这样的事情?

使用的readerwriterlock实现的简化版本如下所示:

private const int readwriterlocktimeoutms = 5000; private static ReaderWriterLock readerWriterLock = new ReaderWriterLock(); // this method will be called by thread A public static void MethodA() { // bool to indicate that we have the lock bool IsTaken = false; try { // get the lock readerWriterLock.AcquireWriterLock(readwriterlocktimeoutms); // log that we have the lock for debug // Logger.LogInfo("MethodA: acquired write lock; writer lock held {0}; reader lock held {1}", readerWriterLock.IsWriterLockHeld.ToString(),readerWriterLock.IsReaderLockHeld.ToString(), ); // mark that we have taken the lock IsTaken = true; } catch(Exception e) { throw new Exception(string.Format("Error getting lock {0} {1}", e.Message, Environment.StackTrace)); } try { // do some work } finally { if (IsTaken) { readerWriterLock.ReleaseWriterLock(); } } } // this method will be called by thread B public static void MethodB() { // bool to indicate that we have the lock bool IsTaken = false; try { // get the lock readerWriterLock.AcquireReaderLock(readwriterlocktimeoutms); // log that we have the lock for debug // Logger.LogInfo("MethodB: acquired read lock; writer lock held {0}; reader lock held {1}", readerWriterLock.IsWriterLockHeld.ToString(),readerWriterLock.IsReaderLockHeld.ToString(), ); // mark that we have taken the lock IsTaken = true; } catch (Exception e) { throw new Exception(string.Format("Error getting lock {0} {1}", e.Message, Environment.StackTrace)); } try { // do some work } finally { if (IsTaken) { readerWriterLock.ReleaseReaderLock(); } } } enter code here 

@All终于有了解决这个问题的方法。 @Yannick,你走在正确的轨道上……

如果MSDN说不可能同时保持读写器锁定。

今天我得到了微软的确认,在多处理器系统负载很重的情况下(注意:我永远无法在Intel系统上重现这个问题),这可能会导致ReaderWriterLock类对象损坏,如果这种情况有可能增加任何给定阶段的作者数量都会增长,因为这些可以在队列中备份。

在过去的两周里,我一直在运行使用.Net 3.5 ReaderWriterLockSlim类并且没有遇到过这个问题,这与微软已经确认readerwriterlockslim类没有胖胖的ReaderWriterLock类具有相同的破坏风险相对应。

如果MSDN 说不可能同时保持读写器锁定。 由于某些其他原因,您的过程中是否有可能随时拥有2个readerWriterLock对象?

另一件奇怪的事情是,使用isWriterLockHeld调试一个线程,而当前线程是一个读者,不要让你知道在另一个线程中写入。 你怎么知道线程A仍然保持一个写入器锁,你怎么知道它不是调试日志系统延迟或“混合”线程给出的指令?

其他想法,是否有可能共享其他资源导致死锁? 这会以某种方式导致崩溃? (虽然Null Exception仍然很奇怪,除非考虑清除死锁和readerWriterLock重置。

你的问题很奇怪,也是如此。

和其他问题,这不会解决你的问题。 您使用的是什么,而在调试您的应用程序时,您依赖isWriterLockHeld(或isReaderLockHeld)? 为什么不在你的finally块中使用它?